____ _ _ _ _
| _ \ ___ | |_ (_) _ __ ___ __| | (_) __ _
| |_) | / _ \ | __| | | | '_ \ / _ \ / _| | | | / _ |
| _ < | __/ | |_ | | | |_) | | __/ | (_| | | | | (_| |
|_| \_\ \___| \__| |_| | .__/ \___| \__,_| |_| \__,_|
|_|
- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b- `b
Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―Β―
Generische Programmierung in Java
part 4/6 Β· 18.5 KB total
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
DoubleObject<Integer> i = new DoubleObject<>(123, 456);
System.out.println("DoubleObject<String> s=" + s.toString());
System.out.println("DoubleObject<Integer> i=" + i.toString());
}
}
VarianzfΓ€lle
In Java kΓΆnnen die nachfolgenden VarianzfΓ€lle unterschieden werden. Sie bieten jeweils eine vΓΆllig eigenstΓ€ndige FlexibilitΓ€t beim Umgang mit generischen Typen und sind jeweils absolut statisch typsicher.
Invarianz
Bei Invarianz ist der Typparameter eindeutig. Damit bietet Invarianz die grΓΆΓtmΓΆgliche Freiheit bei der Benutzung des Typparameters. Beispielsweise sind fΓΌr die Elemente einer ArrayList<Integer> alle Aktionen erlaubt, die auch bei der direkten Benutzung eines einzelnen Integers erlaubt sind (inklusive Autoboxing). Beispiel:
List<Integer> list = new ArrayList<Integer>();
// ...
Integer x = list.get(index);
list.get(index).methodeVonInteger();
list.set(index, 98347); // Autoboxing, entspricht Integer.valueOf(98347)
int y = list.get(index); // Auto-Unboxing
Diese MΓΆglichkeiten werden mit wenig FlexibilitΓ€t bei der Zuweisung von Objekten der generischen Klasse selbst erkauft. Beispielsweise ist Folgendes nicht erlaubt:
List<Number> list = new ArrayList<Integer>();
und das, obwohl Integer von Number abgeleitet ist. Der Grund liegt darin, dass der Compiler hier nicht mehr sicherstellen kann, dass keine Typfehler auftreten. Mit Arrays, die eine solche Zuweisung erlauben, hat man schlechte Erfahrungen gemacht:
// OK, Integer[] ist abgeleitet von Number[]
Number[] array = new Integer[10];
// ArrayStoreException zur Laufzeit: Double -> Integer sind nicht
// zuweisungskompatibel
array[0] = new Double(5.0);
Kovarianz
Man bezeichnet Arrays als kovariant, was besagt:
Aus
T extends V
folgt:
T[] extends V[]
oder allgemeiner:
Aus
T extends V
folgt:
GenerischerTyp<T> extends GenerischerTyp<V>
Es verhΓ€lt sich also der Array-Typ bzgl. der Vererbungshierarchie genauso wie der Typparameter. Kovarianz ist auch mit generischen Typen mΓΆglich, allerdings nur mit EinschrΓ€nkungen, so dass Typfehler zur Kompilierzeit ausgeschlossen werden kΓΆnnen.
Referenzen mΓΌssen mit der Syntax ? extends T explizit als kovariant gekennzeichnet werden. T heiΓt upper typebound, also der allgemeinste Typparameter, der erlaubt ist.
List<? extends Number> list;
list = new ArrayList<Double>();
list = new ArrayList<Long>();
list = new ArrayList<Integer>();
// Typfehler vom Compiler
list.set(index, myInteger);
// OK aber Warnung vom Compiler: unchecked cast
((List<Integer>) list).set(index, myInteger);
Das Ablegen von Elementen in diesen Listen ist nicht mΓΆglich, da dies, wie oben beschrieben, nicht typsicher ist (Ausnahme: null kann abgelegt werden). Bereits zur Kompilierzeit tritt ein Fehler auf. Allgemeiner gesagt, ist die Zuweisung
?
β
? extends T
nicht erlaubt.
MΓΆglich dagegen ist das Auslesen von Elementen:
Number n = list.get(index); // OK
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ